package lv.solcraft.replication.client.boot;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.util.Assert;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.BaseException;

public class ClientBootConfig {

    private String dbDriver = "";
    private String dbUrl = "";
    private String dbUser = "";
    private String dbPassword = "";
    private String clientName = "";
    private String serverName = "";
    private String scheduleCron = "";
    private String serverUrl = "";
    private File replHome;

    public String getScheduleCron() {
        return scheduleCron;
    }

    public void setScheduleCron(String scheduleCron) {
        this.scheduleCron = scheduleCron;
    }

    public String getClientName() {
        return clientName;
    }

    public void validate() {
        // TODO add client settings validation
    }

    public void copyFrom(ClientBootConfig other) {
        try {
            BeanUtils.copyProperties(this, other);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to copy client boot config", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Failed to copy client boot config", e);
        }
    }

    public static ClientBootConfig fromXML(File file) {
        XStream xstream = new XStream();
        xstream.setMode(XStream.NO_REFERENCES);
        xstream.alias("client", ClientBootConfig.class);
        try {
            ClientBootConfig client = (ClientBootConfig) xstream.fromXML(FileUtils.readFileToString(file));
            client.setClientName(parseClientName(file));
            return client;
        } catch (BaseException e) {
            throw new IllegalArgumentException("Error while parsing client config xml file: " + file, e);
        } catch (IOException e) {
            throw new IllegalArgumentException("Error while parsing client config xml file: " + file, e);
        }
    }

    public static String parseClientName(File file) {
        Assert.isTrue(file.getName().endsWith(".client.xml"), "Invalid client file name: " + file.getName());
        return file.getName().split("[.]")[0];
    }

    public String getServerName() {
        return serverName;
    }

    public String getDbDriver() {
        return dbDriver;
    }

    public void setDbDriver(String dbDriver) {
        this.dbDriver = dbDriver;
    }

    public String getDbUrl() {
        return dbUrl;
    }

    public void setDbUrl(String dbUrl) {
        this.dbUrl = dbUrl;
    }

    public String getDbUser() {
        return dbUser;
    }

    public void setDbUser(String dbUser) {
        this.dbUser = dbUser;
    }

    public String getDbPassword() {
        return dbPassword;
    }

    public void setDbPassword(String dbPassword) {
        this.dbPassword = dbPassword;
    }

    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    public Properties asProperties() {
        Properties props = new Properties();
        props.put("dbDriver", dbDriver);
        props.put("dbUrl", dbUrl);
        props.put("dbUser", dbUser);
        props.put("dbPassword", dbPassword);
        props.put("clientName", clientName);
        props.put("serverName", serverName);
        props.put("scheduleCron", scheduleCron);
        props.put("serverUrl", serverUrl);
        return props;
    }

    public String getServerUrl() {
        return serverUrl;
    }

    public void setServerUrl(String serverUrl) {
        this.serverUrl = serverUrl;
    }

    public File getReplHome() {
        return replHome;
    }

    public void setReplHome(File replHome) {
        this.replHome = replHome;
    }

    public File getLogDir() {
        File file = new File(replHome, "clients-log");
        file.mkdirs();
        return file;
    }
}
